package whereRU.frontEnd;

import java.util.ArrayList;

import database.CourseDbAdapter;
import database.MapDbAdapter;

import routeFunctions.GPS;
import routeFunctions.Loc;

import whereRU.frontEnd.R;
import android.app.Activity;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.Toast;

/** 
 * Activity that gives allows the user to request directions
 */
public class DirectionsActivity extends Activity {
	public static final String EXTRA_START_BUILDING = "sp.whereru.START_BUILDING";
	public static final String EXTRA_END_BUILDING = "sp.whereru.END_BUILDING";
	public static final String EXTRA_START_ROOM = "sp.whereru.START_ROOM";
	public static final String EXTRA_END_ROOM = "sp.whereru.END_ROOM";
	public static final String NO_ROOMS = "N/A";
	private static final Loc STUDENTCENTER = new Loc(39.709163, -75.118260); 
	private GPS gps;
	private boolean hasFix;
	
	CourseDbAdapter courseDbAdapter;
	MapDbAdapter mapDbAdapter;

	Spinner buildingsStartSpinner;
	Spinner buildingsEndSpinner;
	Spinner roomStartSpinner;
	Spinner roomEndSpinner;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.directions);
		
		gps = new GPS(this);
		hasFix = false;

		mapDbAdapter = new MapDbAdapter(this);
		mapDbAdapter.open();

		buildingsStartSpinner = (Spinner) findViewById(R.id.buildings_start_spinner);
		buildingsEndSpinner = (Spinner) findViewById(R.id.buildings_end_spinner);
		roomStartSpinner = (Spinner) findViewById(R.id.room_start_spinner);
		roomEndSpinner = (Spinner) findViewById(R.id.room_end_spinner);

		// set the adapter for the building spinners
		ArrayList<String> buildingNames = mapDbAdapter.getBuildingNames(false);
		ArrayAdapter<String> buildingAdapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, buildingNames);
		buildingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		buildingsStartSpinner.setAdapter(buildingAdapter);
		buildingsEndSpinner.setAdapter(buildingAdapter);

		// update both room spinners
		updateRoomSpinner(buildingsStartSpinner, roomStartSpinner);
		roomEndSpinner.setAdapter(roomStartSpinner.getAdapter());

		AdapterView.OnItemSelectedListener startSpinnerListener = new AdapterView.OnItemSelectedListener() {
			public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
				updateRoomSpinner((Spinner) parent, roomStartSpinner);
			}
			public void onNothingSelected(AdapterView<?> parent) { }
		};
		AdapterView.OnItemSelectedListener endSpinnerListener = new AdapterView.OnItemSelectedListener() {
			public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
				updateRoomSpinner((Spinner) parent, roomEndSpinner);
			}
			public void onNothingSelected(AdapterView<?> parent) { }
		};

		buildingsStartSpinner.setOnItemSelectedListener(startSpinnerListener);
		buildingsEndSpinner.setOnItemSelectedListener(endSpinnerListener);

		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		if(extras == null) { /* do nothing */ }
		else {
			long courseId = extras.getLong(CourseAlarmManager.EXTRA_COURSE_ID);
			courseDbAdapter = new CourseDbAdapter(this);
			courseDbAdapter.open();
			Course course = courseDbAdapter.returnCourse(courseId);
			courseDbAdapter.close();
			String theBuilding = course.getBuilding();
			String theRoom = course.getRoomNum();

			// set the end building spinner to the correct selection
			for(int i = 0; i < buildingsEndSpinner.getCount(); i++) {
				if(theBuilding.equals(buildingsEndSpinner.getItemAtPosition(i).toString()))
					buildingsEndSpinner.setSelection(i, true);
			}

			// get the list of classrooms from the selected building
			String sBuilding = buildingsEndSpinner.getSelectedItem().toString();
			ArrayList<String> sClassrooms = mapDbAdapter.getRooms(sBuilding);

			ArrayAdapter<String> roomEndAdapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_spinner_item, sClassrooms);
			roomEndAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			roomEndSpinner.setAdapter(roomEndAdapter);
			for(int j = 0; j < roomEndSpinner.getCount(); j++) {
				if(theRoom.equals(roomEndSpinner.getItemAtPosition(j)))
					roomEndSpinner.setSelection(j, true);
			}
		}
	}

	/**
	 * Called when the activity is destroyed.
	 * Close the database.
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		mapDbAdapter.close();
	}

	/** 
	 * Updates the rooms spinner based on a building spinner
	 * @param buildingSpinner	the building spinner
	 * @param roomSpinner		the room spinner
	 */
	private void updateRoomSpinner(Spinner buildingSpinner, Spinner roomSpinner) {
		// find the building in the spinner
		String sBuilding = buildingSpinner.getSelectedItem().toString();
		ArrayList<String> sClassrooms = mapDbAdapter.getRooms(sBuilding);

		if(sClassrooms.size() == 0)
			sClassrooms.add(NO_ROOMS);

		ArrayAdapter<String> roomAdapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, sClassrooms);
		roomAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		roomSpinner.setAdapter(roomAdapter);
	}

	/**
	 * Shows the map with highlighted buildings
	 * @param view the view
	 */
	public void showMap(View view) {
		Spinner buildingsStartSpinner = (Spinner) findViewById(R.id.buildings_start_spinner);
		Spinner buildingsEndSpinner = (Spinner) findViewById(R.id.buildings_end_spinner);
		Spinner roomStartSpinner = (Spinner) findViewById(R.id.room_start_spinner);
		Spinner roomEndSpinner = (Spinner) findViewById(R.id.room_end_spinner);		
		RadioButton gpsButton = (RadioButton) findViewById(R.id.gpsButton);
		RadioButton netButton = (RadioButton) findViewById(R.id.networkButton);	
		CheckBox checkBox = (CheckBox) findViewById(R.id.userLocBox);

		String sStartBuilding = buildingsStartSpinner.getSelectedItem().toString();
		String sEndBuilding = buildingsEndSpinner.getSelectedItem().toString();
		String sStartRoom = roomStartSpinner.getSelectedItem().toString();
		String sEndRoom = roomEndSpinner.getSelectedItem().toString();

		Intent intent = new Intent(this, MapViewActivity.class);
		if(checkBox.isChecked()) {
			if(gpsButton.isChecked() || netButton.isChecked()) {
				if(netButton.isChecked())
					hasFix = false;
				doGPS();
			}
			else{
				Toast.makeText(getApplicationContext(), "You must select a Location Provider first!", Toast.LENGTH_LONG).show();
				return;
			}
		}
		else {
			// if the user is requesting directions to the same room, return
			if(sEndBuilding.equals(sStartBuilding) && 
					sStartRoom.equals(sEndRoom)) {
				Toast.makeText(this, "You have arrived at your destination.", Toast.LENGTH_LONG).show();
				return;
			}
			intent.putExtra(EXTRA_START_BUILDING, sStartBuilding);
			intent.putExtra(EXTRA_START_ROOM, sStartRoom);
		}
		intent.putExtra(EXTRA_END_BUILDING, sEndBuilding);
		intent.putExtra(EXTRA_END_ROOM, sEndRoom);
		startActivity(intent);
	}

	/**
	 * Event to handle the Use Location CheckBox event.
	 * @param view The view that fired the event.
	 */
	public void checkBoxClick(View view) {		
		Spinner buildingsStartSpinner = (Spinner) findViewById(R.id.buildings_start_spinner);
		Spinner roomStartSpinner = (Spinner) findViewById(R.id.room_start_spinner);
		RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
		CheckBox checkBox = (CheckBox) findViewById(R.id.userLocBox);
		RadioButton gpsButton = (RadioButton) findViewById(R.id.gpsButton);		
		Button fix = (Button) findViewById(R.id.gpsFixButton);
		if(checkBox.isChecked()){
			buildingsStartSpinner.setEnabled(false);
			roomStartSpinner.setEnabled(false);
			radioGroup.setVisibility(View.VISIBLE);
			if(gpsButton.isChecked())
				fix.setVisibility(View.VISIBLE);
			else
				fix.setVisibility(View.GONE);
		}
		else{
			buildingsStartSpinner.setEnabled(true);
			roomStartSpinner.setEnabled(true);
			radioGroup.setVisibility(View.GONE);
			fix.setVisibility(View.GONE);
		}
	}

	/**
	 * Called when the user clicks one of the radio buttons
	 * @param view
	 */
	public void radioClick(View view) {		
		RadioButton gpsButton = (RadioButton) findViewById(R.id.gpsButton);
		RadioButton netButton = (RadioButton) findViewById(R.id.networkButton);
		Button fix = (Button) findViewById(R.id.gpsFixButton);
		if(gpsButton.isChecked()) {
			gps.setProvider(LocationManager.GPS_PROVIDER);
			fix.setVisibility(View.VISIBLE);
		}
		else if(netButton.isChecked()) {
			gps.setProvider(LocationManager.NETWORK_PROVIDER);
			fix.setVisibility(View.GONE);
		}
	}	

	/**
	 * Called when the user requests to get a gps fix
	 * @param view
	 */
	public void getFix(View view) {	
		doGPS();
	}

	/**
	 * Obtain a user's current location
	 */
	private void doGPS(){
		if(!hasFix){
			gps.startGPS();
			Loc userLoc;
			int temp = gps.getCoordinates();
			if(temp == -2){
				userLoc = STUDENTCENTER;
			}
			else {
				if(temp == 1)
					userLoc = gps.getLastLoc();
				else if(temp == 0){
					userLoc = gps.getLastLoc();
					Toast.makeText(this, "Location has not changed.", Toast.LENGTH_LONG).show();
				}
				else {
					userLoc = STUDENTCENTER;
					Toast.makeText(this, "Location could not be determined.", Toast.LENGTH_LONG).show();
				}
			gps.stopGPS();
			}
			hasFix =true;
			((MyApplication) this.getApplication()).setUserLocation(userLoc);
		}
	}
}